using MassTransit;
using WeatherSystem.API.Services.MessageQueue;

namespace WeatherSystem.API.Configurations
{
    /// <summary>
    /// RabbitMQ消息队列配置
    /// </summary>
    public static class RabbitMQConfiguration
    {
        public static IServiceCollection AddRabbitMQServices(this IServiceCollection services, IConfiguration configuration)
        {
            var rabbitMQConfig = configuration.GetSection("RabbitMQ");
            var connectionString = Environment.GetEnvironmentVariable("RABBITMQ_CONNECTION_STRING") 
                ?? rabbitMQConfig["ConnectionString"] 
                ?? "amqp://guest:guest@localhost:5672/";

            services.AddMassTransit(x =>
            {
                // 注册消费者
                x.AddConsumer<WeatherDataCollectionTaskConsumer>(typeof(WeatherDataCollectionTaskConsumerDefinition));
                x.AddConsumer<BatchDataProcessingTaskConsumer>(typeof(BatchDataProcessingTaskConsumerDefinition));
                x.AddConsumer<DataExportTaskConsumer>(typeof(DataExportTaskConsumerDefinition));
                x.AddConsumer<AlertNotificationConsumer>(typeof(AlertNotificationConsumerDefinition));
                x.AddConsumer<SystemEventConsumer>(typeof(SystemEventConsumerDefinition));

                x.UsingRabbitMq((context, cfg) =>
                {
                    cfg.Host(connectionString);

                    // 配置重试策略
                    cfg.UseMessageRetry(r => r.Exponential(3, TimeSpan.FromSeconds(1), TimeSpan.FromSeconds(30), TimeSpan.FromSeconds(2)));

                    // 配置错误处理
                    cfg.UseInMemoryOutbox(context);

                    // 配置消费者端点
                    cfg.ReceiveEndpoint("weather-data-collection", e =>
                    {
                        e.ConfigureConsumer<WeatherDataCollectionTaskConsumer>(context);
                        e.Durable = true;
                        e.PrefetchCount = 16;
                        e.ConcurrentMessageLimit = 8;
                    });

                    cfg.ReceiveEndpoint("batch-data-processing", e =>
                    {
                        e.ConfigureConsumer<BatchDataProcessingTaskConsumer>(context);
                        e.Durable = true;
                        e.PrefetchCount = 8;
                        e.ConcurrentMessageLimit = 4;
                    });

                    cfg.ReceiveEndpoint("data-export", e =>
                    {
                        e.ConfigureConsumer<DataExportTaskConsumer>(context);
                        e.Durable = true;
                        e.PrefetchCount = 4;
                        e.ConcurrentMessageLimit = 2;
                    });

                    cfg.ReceiveEndpoint("alert-notifications", e =>
                    {
                        e.ConfigureConsumer<AlertNotificationConsumer>(context);
                        e.Durable = true;
                        e.PrefetchCount = 32;
                        e.ConcurrentMessageLimit = 16;
                    });

                    cfg.ReceiveEndpoint("system-events", e =>
                    {
                        e.ConfigureConsumer<SystemEventConsumer>(context);
                        e.Durable = true;
                        e.PrefetchCount = 64;
                        e.ConcurrentMessageLimit = 32;
                    });

                    // 配置发布确认
                    // UsePublishConfirms 在新版本中可能已被移除或重命名
                });

                // 配置调度器（如果需要延迟消息）
                x.AddDelayedMessageScheduler();
            });

            // 注册消息队列服务
            services.AddScoped<IMessageQueueService, RabbitMQService>();

            return services;
        }
    }

    // 消费者定义类，用于配置特定的消费者行为
    public class WeatherDataCollectionTaskConsumerDefinition : ConsumerDefinition<WeatherDataCollectionTaskConsumer>
    {
        [Obsolete("This method is obsolete in MassTransit 8.x, but required for compatibility")]
        protected override void ConfigureConsumer(IReceiveEndpointConfigurator endpointConfigurator,
            IConsumerConfigurator<WeatherDataCollectionTaskConsumer> consumerConfigurator)
        {
            consumerConfigurator.UseRetry(r => r.Intervals(100, 200, 500, 800, 1000));
            consumerConfigurator.UseInMemoryOutbox();
        }
    }

    public class BatchDataProcessingTaskConsumerDefinition : ConsumerDefinition<BatchDataProcessingTaskConsumer>
    {
        [Obsolete("This method is obsolete in MassTransit 8.x, but required for compatibility")]
        protected override void ConfigureConsumer(IReceiveEndpointConfigurator endpointConfigurator,
            IConsumerConfigurator<BatchDataProcessingTaskConsumer> consumerConfigurator)
        {
            consumerConfigurator.UseRetry(r => r.Intervals(200, 500, 1000, 2000));
            consumerConfigurator.UseInMemoryOutbox();
        }
    }

    public class DataExportTaskConsumerDefinition : ConsumerDefinition<DataExportTaskConsumer>
    {
        [Obsolete("This method is obsolete in MassTransit 8.x, but required for compatibility")]
        protected override void ConfigureConsumer(IReceiveEndpointConfigurator endpointConfigurator,
            IConsumerConfigurator<DataExportTaskConsumer> consumerConfigurator)
        {
            consumerConfigurator.UseRetry(r => r.Intervals(500, 1000, 2000));
            consumerConfigurator.UseInMemoryOutbox();
        }
    }

    public class AlertNotificationConsumerDefinition : ConsumerDefinition<AlertNotificationConsumer>
    {
        [Obsolete("This method is obsolete in MassTransit 8.x, but required for compatibility")]
        protected override void ConfigureConsumer(IReceiveEndpointConfigurator endpointConfigurator,
            IConsumerConfigurator<AlertNotificationConsumer> consumerConfigurator)
        {
            consumerConfigurator.UseRetry(r => r.Intervals(100, 500, 1000));
            consumerConfigurator.UseInMemoryOutbox();
        }
    }

    public class SystemEventConsumerDefinition : ConsumerDefinition<SystemEventConsumer>
    {
        [Obsolete("This method is obsolete in MassTransit 8.x, but required for compatibility")]
        protected override void ConfigureConsumer(IReceiveEndpointConfigurator endpointConfigurator,
            IConsumerConfigurator<SystemEventConsumer> consumerConfigurator)
        {
            consumerConfigurator.UseRetry(r => r.Intervals(50, 100, 200));
            consumerConfigurator.UseInMemoryOutbox();
        }
    }
}